/**
 * 作业请求的处理入口
 * 
 * Created by wbx on 2022/5/1
 */
(() => {
  // 私有区域

  return async function ({ Name, Param = {}, Token, ...Args }, headers) {
    if (!Name) throw Error("The job name is missing");
    if (Name === 'Process') throw Error("invalid job name");

    Object.assign(Param, Args);

    // 优先使用Headers中的JWT会话令牌
    if (headers && 'Authorization' in headers) {
      Token = headers['Authorization'][0];
      if (Token.startsWith('Bearer ')) {
        Token = Token.substr(7);
      }
    }

    // 验证会话信息
    if (Token) {
      try {
        let payload = A.jwt.verify(Token);
        Object.assign(Param, payload);
      } catch (e) {
        Logger.Warn(e.message);
      }
    } else {
      delete Param.UID;
    }

    // 检查作业访问控制表
    if (headers && A.setting('EnableJobACL')) {
      const acl = A.cache.get(`JobACL.${Name}`, () => {
        return A.db.execute('KERNEL', "SELECT KFJK, GLYM_ID FROM ZYFWKZ WHERE ZYMC=?", [Name]).rows;
      }, 60); // 缓存60秒
      if (!acl.some(item => !!item.KFJK) && !A.job.JobEvent({
        Event: 'OnCheckPageACL',
        UID: Param.UID,
        PageIds: acl.filter(item => item.GLYM_ID).map(item => item.GLYM_ID),
      }, headers)) {
        throw Error("You are not authorized to access this job");
      }
    }

    try {
      const Result = await A.job[Name](Param, headers);
      if (Name !== 'JobEvent') A.job.JobEvent({ Event: 'OnJobInvoke', Name, Param, Result, Success: true }, headers);
      return Result;
    } catch (e) {
      if (Name !== 'JobEvent') A.job.JobEvent({ Event: 'OnJobInvoke', Name, Param, Result: e, Success: false }, headers);
      throw e;
    }
  };
})();